(function (fruit, util) {

    var _util = fruit.graphic.util;


    fruit.define("fruit.graphic.TopologyGroup", {
        events: ["Over", "Out", "Select"],
        properties: {
            maskBound: {
                value: null
            },
            groupsNumber: {
                value: null
            }
        },
        methods: {
            init: function (items, key, index, context) {
                this.items = items;
                this.key = key;
                this.context = context;
                this.index = index;
                this.draw();
            },
            draw: function () {
                var element = this.element = _util.create("g")
                    .attr("pointer-events", "all")
                    .classed("group", true)
                    .attr("id", this.key);
                this.path = element.append("path").attr("class", "node_group");
                //this.redraw();
            },
            redraw: function () {
                var self = this;
                var vertices = [];
                var gap = 1;
                fruit.util.each(this.items, function (node) {
                    var bound = node.position();
                    vertices.push([bound.x, bound.y]);
                });


                vertices = _.uniq(vertices, function (d) {
                    return d[0] + "_" + d[1]
                });

                if (vertices.length == 1) {
                    var point = vertices[0];
                    vertices.push([point[0] - gap, point[1] - gap]);
                    vertices.push([point[0] + gap, point[1] - gap]);
                } else if (vertices.length == 2) {
                    vertices.push([vertices[0][0] + 1, vertices[0][1] + 1]);
                    vertices.push(vertices[1]);

                }

                var path = "M" + d3.geom.hull(vertices).join("L") + "Z";
                var strokeWidth = this.strokeWidth = 44 + 20 * this.context.scale();
                this.path.attr("d", path).style({"stroke-width": strokeWidth});

//                if (this.timer) {
//                    clearTimeout(this.timer);
//                }
//                this.timer = setTimeout(function () {
                try {
                    var bound = self.path.node().getBBox();
                    var padding = 10;
                    if (!self.bg) {
                        self.bg = self.element.append("rect").style('fill', 'transparent');
                    }
                    self.bg.attr({
                        x: bound.x - strokeWidth / 2 - padding,
                        y: bound.y - strokeWidth / 2 - padding,
                        width: bound.width + strokeWidth + padding * 2,
                        height: bound.height + strokeWidth + padding * 2
                    });
                } catch (e) {

                }

                //}, 100);
            },
            clean: function () {
                this.content.remove();
            },
            select: function () {
                this._drawMask(0);
            },

            unSelect: function () {
                var self = this;
                this._drawMask();
                setTimeout(function () {
                    self.recover();
                }, 400);
            },
            _drawMask: function (inGap) {
                var gap = inGap || (inGap == 0 ? 0 : 30);
                var strokeWidth = this.strokeWidth;
                var bound = this.maskBound();
                var maskData = [
                    [bound.x - strokeWidth, bound.y - strokeWidth - gap],
                    [bound.x + bound.width + strokeWidth, bound.y - strokeWidth + gap],
                    [bound.x + bound.width + strokeWidth, bound.y + bound.height + strokeWidth - gap],
                    [bound.x - strokeWidth, bound.y + bound.height + strokeWidth + gap]
                ];
                this.mask.attr("d", "M" + maskData.join("L") + "Z");
            },
            fadeIn: function () {
                this.element.attr("class", "group group_fadeIn");
                this.path.attr("class", "node_group node_group_fadeIn");
            },
            recover: function () {
                this.element.attr("class", "group");
                this.path.attr("class", "node_group");

            },
            fadeOut: function () {
                this.element.attr("class", "group group_fadeOut");
                this.path.attr("class", "node_group node_fadeOut");
            },

            bound: function () {
                return this.path.node().getBBox();
            }
        }
    })

})(fruit, fruit.util);
